// UserService.java
package com.xiaocikuai.smallchunks.service.User;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaocikuai.smallchunks.entity.User.*;
import com.xiaocikuai.smallchunks.file.PutObject004;
import com.xiaocikuai.smallchunks.mapper.User.UserMapper;
import com.xiaocikuai.smallchunks.service.Pay.WX_PayServiceImpl;
import com.xiaocikuai.smallchunks.service.Transaction.RandomCode;
import com.xiaocikuai.smallchunks.utils.JWTservice.JwtService;
import com.xiaocikuai.smallchunks.utils.SessionListener;
import com.xiaocikuai.smallchunks.utils.resultd.PageResult;
import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class UserService extends ServiceImpl<UserMapper, User> {
    @Resource
    private UserMapper userMapper;

    @Resource
    private JCacheCacheManager cacheManager;
    @Resource
    private JwtService jwtService;

    @Resource
    private RandomCode randomCode;


    @Autowired
    private PutObject004 putObject004;

    @Resource
    private SessionListener sessionListener;
    @Resource
    private WX_PayServiceImpl wxPayService;
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");


    //用户注册
    public String registerUser(User user) {
        if (!userMapper.chaxu(user.getUsername())) {
            String code = getCode(user.getUsername());
            if (!code.equals("无效的验证码")) {
                if (isCode(code, user.getCode())){
                    user = setUser(user);
                    if (userMapper.insert(user)==1) {
                        deleteCode(user.getUsername());
                        return "success";
                    } else
                        return "注册失败，请稍后重试";
                } else
                   return "验证码错误";
            } else
                return code;
        } else
            return "该手机号已被使用";
    }

    public boolean testInsert(User user){
        if (!userMapper.chaxu(user.getUsername())){
        user = setUser(user);
        return  userMapper.insert(user)==1;
    } else
            return false;
    }
    //初始化用户
    public User setUser(User user){
        Integer id =  userMapper.selectSpreadId(user.getUniquecode());
        if (id != null)
            user.setSpreadUid(id);
        user.setUniquecode(randomCode.getLoginUnique());
        user.setPassword(encodePassword(user.getPassword()));
        return user;
    }


    public String getCode(String username){
        Cache cache = cacheManager.getCache("verificationCodes");
        Cache.ValueWrapper valueWrapper = cache.get(username);
        if (valueWrapper == null){
            return "无效的验证码";
        }
        return  (String) valueWrapper.get();
    }

     public void deleteCode(String username){
        Cache cache = cacheManager.getCache("verificationCodes");
        cache.evict(username);
    }

     //用户账号密码登录
    public String loginWithUsernameAndPassword(Login login, HttpServletResponse response) {
        if (userMapper.chaxu(login.getUsername())) {
            String encryptedPassword = encodePassword(login.getPassword());
            if (userMapper.login(login.getUsername(), encryptedPassword)) {
                Date time = new Date();
                userMapper.updateTime(login.getUsername(), time);
                return "success";
            } else {
                return "登录失败";
            }
        }else
            return "该手机号未注册";
    }

     //验证码密码校验
    public String loginWithCode(Login login) {
        if (userMapper.chaxu(login.getUsername())){
            String code = getCode(login.getUsername());
            if (!code.equals("无效的验证码")) {
                if (isCode(code,login.getCode())){
                    return "success";
                } else
                    return "验证码错误";
            } else
                return code;
        }else
            return "该手机号未注册";
    }

    public boolean isCode(String target, String nowCode) {
        if (!target.matches("\\d{14}_\\d{6}")) {
            throw new IllegalArgumentException("Invalid target format: " + target);
        }         //分割字符串
        String[] parts = target.split("_");
        String targetTimeStr = parts[0];
        String targetCodeStr = parts[1];
        // 解析目标时间字符串
        LocalDateTime targetTime = LocalDateTime.parse(targetTimeStr, formatter);
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 计算时间差
        long minutesDifference = ChronoUnit.MINUTES.between(targetTime, now);
        // 检查时间差和验证码是否匹配
        return minutesDifference <= 5 && targetCodeStr.equals(nowCode);
    }

    // 将 Token 添加到 Cookie
    public void addTokenCookie(HttpServletResponse response, String token) {
        Cookie cookie = new Cookie("token", token);
        cookie.setHttpOnly(true); // 禁止 JavaScript 访问此 Cookie
        cookie.setSecure(true); // 仅在 HTTPS 连接中发送此 Cookie
        cookie.setPath("/"); // 设置 Cookie 的路径
        response.addCookie(cookie);
    }

    public static String encodePassword(String password) {
        try {
            // 创建 MessageDigest 实例，并指定算法为 MD5
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 将密码字符串转换为字节数组
            byte[] passwordBytes = password.getBytes();
            // 使用 MessageDigest 对密码字节数组进行加密，得到加密后的字节数组
            byte[] encryptedBytes = md.digest(passwordBytes);
            // 将加密后的字节数组转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : encryptedBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            // 处理加密算法不可用的异常
            return null;
        }
    }

  //分页
   public PageResult page(Integer page,Integer pageSize)
   {

       Long totalCount = userMapper.count();
       int start = (page - 1) * pageSize;
       int totalPages = (int) Math.ceil((double) totalCount / pageSize);
       List<UserVO> userList = userMapper.page(start, pageSize);
       return new PageResult(totalCount, userList, totalPages);
   }

   //条件查询用户列表
   public PageResult<UserVO> searchAndPage(UserQuery query, int page, int pageSize) {
       Long totalCount = userMapper.countByQuery(query); // 根据查询条件统计总记录数
       int start = (page - 1) * pageSize;
       int totalPages = (int) Math.ceil((double) totalCount / pageSize);
       List<UserVO> userList = userMapper.searchAndPage(query, start, pageSize); // 根据查询条件分页查询用户列表
       return new PageResult<>(totalCount, userList, totalPages);
   }

   //签到
    public Sign userSign(String token){
        Sign signs = new Sign();
        int uid = jwtService.deconstruction(token).getUid();
        //用户最后一次签到
        Sign sign = userMapper.getSignDate(uid);
        if (sign == null) {
             //新用户
            int newIntegral = userMapper.getIntegrale(uid);
            int newIntegrals = userMapper.getIntegrales(uid);

            newIntegral += 10;
            newIntegrals += 10;

            userMapper.addSign(uid, "签到奖励", 10, newIntegrals, LocalDate.now(), 0);
            userMapper.updateIntegral( newIntegral, newIntegrals, uid);

            signs.setLevel(0);
            signs.setNumber(10);
            signs.setBalance(newIntegral);

        } else {
             //老用户
             //更新连续签到天数 设置时间
            sign.setLevel(getSignLevel(sign.getCreateTime(),sign.getLevel()));
            sign.setCreateTime(LocalDate.now());

            int newIntegral = userMapper.getIntegrale(uid);
            int newIntegrals = userMapper.getIntegrales(uid);

            newIntegral += 10*sign.getLevel();
            newIntegrals += 10*sign.getLevel();

            userMapper.addSign(uid, "签到奖励", 10*sign.getLevel(), newIntegral, LocalDate.now(), sign.getLevel());
            userMapper.updateIntegral( newIntegral, newIntegrals, uid);

            signs.setLevel(sign.getLevel());
            signs.setNumber(10*sign.getLevel());
            signs.setBalance(newIntegral);
        }
signs.setCreateTime(LocalDate.now());
        return signs;

    }

    //连续签到
    public int getSignLevel(LocalDate last,int level){
        LocalDate now = LocalDate.now();
        if (now.equals(last.plusDays(1))){
            level += 1;
        }else {
            level = 0;
        }
        return level;
    }


    //获得等级
    public int getLevel(int NewIntegrals){
        int level = -1;
        if(NewIntegrals <1000) {
            level = 1;
        } else if(NewIntegrals < 2000) {
            level = 2;
        } else if(NewIntegrals < 5000) {
            level = 3;
        }else if(NewIntegrals < 10000) {
            level = 4;
        }else if(NewIntegrals < 20000) {
            level = 5;
        }else if(NewIntegrals < 50000) {
            level = 6;
        }
        return level;
    }

    //积分
    public int getIntegral(String token){
        int uid = jwtService.deconstruction(token).getUid();
        return userMapper.getIntegrale(uid);
    }

    public UserVO getUser(String token){
        int uid = jwtService.deconstruction(token).getUid();
        UserVO user = userMapper.getUser(uid);
        user.setLevel(getLevel(user.getIntegrals()));
        return user;
    }
    //当日签到
    public int getIsSign(String token){
        int uid = jwtService.deconstruction(token).getUid();
        LocalDate time = LocalDate.now();
        if(userMapper.getIsSign(uid, time) == null){
            return 0;
        }
        return userMapper.getIsSign(uid, time);
    }

    //获取用户等级






    public Map<String, Object> getOnlineUsersInfo() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        // 统计各平台的在线人数
        int totalOnlineCount = onlineUsers.size();
        int appOnlineCount = 0;
        int miniProgramOnlineCount = 0;
        int websiteOnlineCount = 0;
        int unknownPlatformCount = 0;

        for (UserOnline user : onlineUsers) {
            String platform = user.getPlatform();
            if (platform != null) {
                switch (platform) {
                    case "app":
                        appOnlineCount++;
                        break;
                    case "小程序":
                        miniProgramOnlineCount++;
                        break;
                    case "网站":
                        websiteOnlineCount++;
                        break;
                    default:
                        unknownPlatformCount++;
                        break;
                }
            } else {
                unknownPlatformCount++;
            }
        }
        // 创建结果对象
        Map<String, Object> result = new HashMap<>();
        result.put("totalOnlineCount", totalOnlineCount);
        result.put("appOnlineCount", appOnlineCount);
        result.put("miniProgramOnlineCount", miniProgramOnlineCount);
        result.put("websiteOnlineCount", websiteOnlineCount);
        result.put("unknownPlatformCount", unknownPlatformCount);
        return result;
    }


    //加密
    public static String encrypt(String plainText) {
        byte[] plainTextBytes = plainText.getBytes();
        return Base64.getEncoder().encodeToString(plainTextBytes);
    }

    // 解密方法
    public static String decrypt(String encodedText) {
        byte[] decodedBytes = Base64.getDecoder().decode(encodedText);
        return new String(decodedBytes);
    }


    public List<UserOnline> getTotalOnlineUsers() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        return onlineUsers;
    }

    public List<UserOnline> getAppOnlineUsers() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        return filterByPlatform(onlineUsers, "app");
    }

    public List<UserOnline> getMiniProgramOnlineUsers() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        return filterByPlatform(onlineUsers, "小程序");
    }

    public List<UserOnline> getWebsiteOnlineUsers() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        return filterByPlatform(onlineUsers, "网站");
    }

    public List<UserOnline> getUnknownPlatformOnlineUsers() {
        List<UserOnline> onlineUsers = sessionListener != null ? sessionListener.getOnlineUsers() : Collections.emptyList();
        return filterByUnknownPlatform(onlineUsers);
    }

    private List<UserOnline> filterByPlatform(List<UserOnline> onlineUsers, String platform) {
        return onlineUsers.stream()
                .filter(user -> platform.equals(user.getPlatform()))
                .toList(); // Java 16+ 中使用 toList() 方法
    }

    private List<UserOnline> filterByUnknownPlatform(List<UserOnline> onlineUsers) {
        return onlineUsers.stream()
                .filter(user -> user.getPlatform() == null || user.getPlatform().isEmpty())
                .toList(); // Java 16+ 中使用 toList() 方法
    }



    //上传用户头像

    public String AddImg(MultipartFile file) {
        return putObject004.uploadFile(file, "useract");
    }


    public boolean updateNickName(String nickName,String token){
        int uid = jwtService.deconstruction(token).getUid();
//        lambdaUpdate().eq(User::getUid,uid).set(User::getNickname,nickName).update();
        return userMapper.updateNick(nickName,uid);
    }

    public boolean updatePassword(String password,String token){
        int uid = jwtService.deconstruction(token).getUid();
        password = encodePassword(password);
       // return lambdaUpdate().eq(User::getUid,uid).set(User::getPassword,password).update();

    return userMapper.updateCode(password,uid);
    }

    public boolean updateAvatar(MultipartFile avatar,String token){
        int uid = jwtService.deconstruction(token).getUid();
        String avatars =  AddImg(avatar);
       // return lambdaUpdate().eq(User::getUid,uid).set(User::getAvatar,avatars).update();
    return userMapper.updateImg(avatars,uid);
    }

    //申请成为分销员
    public String askSales(String token,User user){
        user.setUsername(jwtService.deconstruction(token).getUsername());
        String code = getCode(user.getUsername());
        if (!code.equals("无效的验证码")) {
            if (isCode(code, user.getCode())){
                user.setUid(jwtService.deconstruction(token).getUid());
                user.setMid(-1);
                if (updateById(user)){
                    return "success";
                }else
                    return "申请失败，请稍后重试";

            } else
                return "验证码错误";
        } else
            return code;
    }

    //通过分销员申请
    public boolean passSales(int uid){
        User user = new User();
        user.setUid(uid);
        user.setMid(1);

        return updateById(user);
   }

    //查询所有分销员
    public List<User> selectQuary() {
        LambdaQueryWrapper<User> querywrapper =new LambdaQueryWrapper<>();
         //大于等于1
          querywrapper.ge(User::getMid,1);
          return userMapper.selectList(querywrapper);
    }

    //申请提现
    public String askPayouts(int money,String token,String openId){
        if(money<2000){
            int uid = jwtService.deconstruction(token).getUid();
            User user = userMapper.selectById(uid);
            Integer balance = userMapper.getSaleBalance(uid);
            Integer count = user.getBrokeragePrice();
            if (balance==null)
                balance=0;

            if (balance.equals(user.getBrokeragePrice()) && (count + money > 0)){
                userMapper.insertMemberSale(uid, money, money,(balance+money),-1,openId);
                user.setBrokeragePrice(balance+money);
                userMapper.updateById(user);
                return "申请提现成功";
            }
        } else{
            return "提现金额过大";
        }
        return "申请提现失败";
    }

    //通过提现申请
    public String passPayouts(List<MemberSale> memberSales){
        try{
            Long totalAmount =  Long.valueOf(0);
            for (MemberSale memberSale : memberSales) {
                totalAmount -= memberSale.getMoney();
            }
            Map<String, String> maps = wxPayService.MemberSale(memberSales,totalAmount);
            if (maps.get("batch_status").equals("ACCEPTED")){
                for (MemberSale memberSale : memberSales) {
                    userMapper.updateMemberSale(memberSale);
                }
            }else
                return maps.get("batch_status");
        }
        catch (Exception e){
            return "错误"+e;
        }
        return "操作成功";
    }

    //获取我的分销明细
    public List<MemberSale> selectMemberSale( String token) {
        int uid = jwtService.deconstruction(token).getUid();
        List<MemberSale> memberSales = userMapper.selectMaleSale(uid);
        for(MemberSale memberSale:memberSales){
            if(memberSale.getDivide()<0)
                memberSale.setDivide(memberSale.getDivide() * -1);
        }
         return memberSales;
    }

    //查询未审批提现
    public List<MemberSale> selectMember() {
        return userMapper.selectMale();
    }

    //获取昨日收益
    public int getYesterdayPayouts(String token){
        int uid = jwtService.deconstruction(token).getUid();
        Integer money=userMapper.getYesterdayPayouts(uid);
        if (money == null){
            money=0;
        }
        return money;
    }

    //获取今日收益
    public int getTodayPayouts(String token){
        int uid = jwtService.deconstruction(token).getUid();
        Integer money=userMapper.getTodayPayouts(uid);
        if(money == null){
            money=0;
        }
        return money;
    }



}
